#include "../ExEngine/common/util.h"
#include "../ExEngine/engine/engine.h"
#include "../ExEngine/engine/object.h"
#include "../ExEngine/engine/camera.h"
#include "../ExEngine/render/d3d_mesh.h"
#include "../ExEngine/render/d3d.h"
#include "scene.h"

#define TUNNEL_LIGHT_COUNT 6

TunnelSegement::TunnelSegement()
{
	mPropCount = 0;
	pPropModels = NULL;
	pModel = NULL;
}

HRESULT TunnelSegement::Create(const Vector3f &position)
{
	Release();

	if(FAILED(CEngine::GetInstance()->CreateObject(string("Tunnel.mdl"), &pModel, MODEL_MESH)))
	{
		Release();
		EE_EXCEPTION("Failed to create light model.");
	}

	CObject *pRailing = NULL;
	CObject *pPipes = NULL;
	CObject *pPowerbox = NULL;
	CObject *pLamp = NULL;
	CObject *pGrate = NULL;
	CObject *pPillarPipe = NULL;
	CObject *pAirDuct = NULL;
	
	int propIndex = 0;
	int propBitfield = CUtil::random(128);
	if(propBitfield & 1 && CUtil::probability(0.875f))
	{
		if(SUCCEEDED(CEngine::GetInstance()->CreateObject(string("Railing.mdl"), &pRailing, MODEL_MESH)))
		{
			pRailing->getModel()->setRenderFlags(RENDER_DEFAULT);
			pRailing->setPosition(position);
			mPropCount++;
		}
	}
	if(propBitfield & 2 && CUtil::probability(0.45f))
	{
		if(SUCCEEDED(CEngine::GetInstance()->CreateObject(string("Powerbox.mdl"), &pPowerbox, MODEL_MESH)))
		{
			pPowerbox->getModel()->setRenderFlags(RENDER_DEFAULT);
			pPowerbox->setPosition(position);
			mPropCount++;
		}
	}
	if(propBitfield & 4 && CUtil::probability(0.55f))
	{
		if(SUCCEEDED(CEngine::GetInstance()->CreateObject(string("LightD.mdl"), &pLamp, MODEL_MESH)))
		{
			pLamp->getModel()->setRenderFlags(RENDER_DEFAULT);
			pLamp->setPosition(position);
			mPropCount++;
		}
	}
	if(propBitfield & 8 && CUtil::probability(0.65f))
	{
		if(SUCCEEDED(CEngine::GetInstance()->CreateObject(string("Grate.mdl"), &pGrate, MODEL_MESH)))
		{
			pGrate->getModel()->setRenderFlags(RENDER_DEFAULT);
			pGrate->setPosition(position);
			mPropCount++;
		}
	}
	if(propBitfield & 16 && CUtil::probability(0.5f))
	{
		if(SUCCEEDED(CEngine::GetInstance()->CreateObject(string("WallPipeB.mdl"), &pPillarPipe, MODEL_MESH)))
		{
			pPillarPipe->getModel()->setRenderFlags(RENDER_DEFAULT);
			pPillarPipe->setPosition(position);
			mPropCount++;
		}
	}
	if(propBitfield & 32 && CUtil::probability(0.65f))
	{
		if(SUCCEEDED(CEngine::GetInstance()->CreateObject(string("AirDuct.mdl"), &pAirDuct, MODEL_MESH)))
		{
			pAirDuct->getModel()->setRenderFlags(RENDER_DEFAULT);
			pAirDuct->setPosition(position);
			mPropCount++;
		}
	}

	if(mPropCount > 0)
	{
		pPropModels = EE_NEW CObject* [mPropCount];
		if(pRailing)
			pPropModels[propIndex++] = pRailing;
		if(pPipes)
			pPropModels[propIndex++] = pPipes;
		if(pLamp)
			pPropModels[propIndex++] = pLamp;
		if(pPowerbox)
			pPropModels[propIndex++] = pPowerbox;
		if(pGrate)
			pPropModels[propIndex++] = pGrate;
		if(pPillarPipe)
			pPropModels[propIndex++] = pPillarPipe;
		if(pAirDuct)
			pPropModels[propIndex++] = pAirDuct;
	}

	pModel->getModel()->setRenderFlags(RENDER_DEFAULT);
	pModel->setPosition(position);
	return S_OK;
}
Vector3f TunnelSegement::GetPosition()
{
	return pModel->getPosition();
}
void TunnelSegement::Update(float dt)
{
	pModel->Update(dt);
	for(int i =0; i < mPropCount; i++)
	{
		pPropModels[i]->Update(dt);
	}
}

void TunnelSegement::Draw()
{
	pModel->Draw();
	for(int i =0; i < mPropCount; i++)
	{
		pPropModels[i]->Draw();
	}
}
	
HRESULT TunnelSegement::Release()
{
	
	for(int i =0; i < mPropCount; i++)
	{
		CObject* pProp = pPropModels[i];
		CEngine::GetInstance()->UnregisterObject(pProp);
	}
	EE_SAFEDELETEARRAY(pPropModels);
	mPropCount = 0;
	CEngine::GetInstance()->UnregisterObject(pModel);
	pModel = NULL;
	return S_OK;
}

TunnelLightManager::TunnelLightManager()
{

}

HRESULT TunnelLightManager::Create()
{
	for(int i = 0; i < TUNNEL_LIGHT_COUNT; i++)
	{
		TunnelLight* pLight = EE_NEW TunnelLight();
		pLight->Create();
		mLeftLights.Add(pLight);
	}
	for(int i = 0; i < TUNNEL_LIGHT_COUNT; i++)
	{
		TunnelLight* pLight = EE_NEW TunnelLight();
		pLight->Create();
		mRightLights.Add(pLight);
	}
	return S_OK;
}

float CalcLerp(float frac, float duration)
{
	if(frac > duration || frac < 0.0f || duration == 0.0f)
		return 0.0f;

	if(frac < (duration / 2.0f))
		return 2.0f * (frac/duration);
	else
		return 2.0f - (2.0f * (frac/duration));
}

void TunnelLightManager::Update(float dt)
{
	
	Vector3f cameraPosition = CEngine::GetInstance()->GetCamera()->getPosition();
	
	float tunnelMovement = mCameraLastPosition.x - cameraPosition.x;

	//Think about placing in a traffic light
	if(tunnelMovement != 0.0f)
	{
		int numTrafficLights = mTrafficLights.Count();
		if(numTrafficLights < TRAFFICLIGHT_COUNT)
		{
			if(CUtil::random(1.0f) < 0.01f)//high odds per frame...
			{
				TrafficLight *pTrafficLight = EE_NEW TrafficLight();
				if(SUCCEEDED(pTrafficLight->Create()))
				{
					//Place the light infront of the camera
					const int INSIDE_THRESHOLD = 2;
					float xDisplacement = sqrtf( pow(SPAWN_TRAFFICLIGHT_THRESHOLD - INSIDE_THRESHOLD, 2) - pow((5.0f - cameraPosition.y), 2));

					if(tunnelMovement > 0.0f)
					{
						pTrafficLight->SetPosition(Vector3f(cameraPosition.x - xDisplacement,5.0f,0));
					}
					else
					{
						pTrafficLight->SetPosition(Vector3f(cameraPosition.x + xDisplacement,5.0f,0));
					}

					mTrafficLights.Add(pTrafficLight);
				}
				else
					EE_SAFEDELETE(pTrafficLight);
			}
		}
		for(int i = 0; i < numTrafficLights;i++)
		{
			TrafficLight *pTrafficLight = mTrafficLights[i];
			if(Vector3f::distance(&pTrafficLight->GetPosition(), &cameraPosition) >  SPAWN_TRAFFICLIGHT_THRESHOLD)
			{
				pTrafficLight->Release();
				mTrafficLights.Remove(pTrafficLight);
				//CEngine::GetInstance()->UnregisterObject((CObject*)pTrafficLight);
				i = 0; //ugly but nessiary to ensure all objects get checked
				numTrafficLights = mTrafficLights.Count();
			}
		}
	}

	float minDist = 0xffff;
	unsigned int minDistLightIdx = 0;
	int lightSpacing = 60;
	int cameraPos = (int)(cameraPosition.x / lightSpacing);

	for(int i = 0; i < mTrafficLights.Count();i++)
	{
		TrafficLight* pLight = mTrafficLights[i];
		pLight->Update(dt);
	}

	float fadeRange = lightSpacing * (0.85f * TUNNEL_LIGHT_COUNT);//(lightSpacing/2.0f);

	for(int i = 0, n = mLeftLights.Count(), halfn = n / 2; i < n; i++)
	{
		Vector3f lightPosition = Vector3f((cameraPos + (i - halfn)) * lightSpacing,16.5,9.5);
		TunnelLight* pLight = mLeftLights[i];
		pLight->SetPosition(lightPosition);
		
		float dist = (lightPosition.x - cameraPosition.x);
		float lerp = CalcLerp(dist + (fadeRange / 2.0f), fadeRange);
		pLight->SetVisiblity(lerp);
	}
	for(int i = 0, n = mRightLights.Count(), halfn = n / 2; i < n; i++)
	{
		Vector3f lightPosition = Vector3f((cameraPos + (i - halfn)) * lightSpacing,16.5,-20.5);
		TunnelLight* pLight = mRightLights[i];
		pLight->SetPosition(lightPosition);
		pLight->Update(dt);

		float dist = (lightPosition.x - cameraPosition.x);
		float lerp = CalcLerp(dist + (fadeRange / 2.0f), fadeRange);
		pLight->SetVisiblity(lerp);
	}

	mCameraLastPosition = cameraPosition;
}
void TunnelLightManager::Draw()
{
	for(int i = 0; i < mTrafficLights.Count();i++)
	{
		TrafficLight* pLight = mTrafficLights[i];
		pLight->Draw();
	
	}
	for(int i = 0; i < mLeftLights.Count(); i++)
	{
		TunnelLight* pLight = mLeftLights[i];
		pLight->Draw();
	}
	for(int i = 0; i < mLeftLights.Count(); i++)
	{
		TunnelLight* pLight = mRightLights[i];
		pLight->Draw();
	}
}
HRESULT TunnelLightManager::Release()
{
	for(int i = 0; i < mLeftLights.Count(); i++)
	{
		TunnelLight* pLight = mLeftLights[i];
		if(pLight)
		{
			pLight->Release();
			EE_SAFEDELETE( pLight);
		}
	}
	for(int i = 0; i < mLeftLights.Count(); i++)
	{
		TunnelLight* pLight = mRightLights[i];
		if(pLight)
		{
			pLight->Release();
			EE_SAFEDELETE( pLight);
		}
	}
	return S_OK;
}


TunnelLight::TunnelLight()
{

	pModel = NULL;
	pLight= NULL;
	pFlare= NULL;
}

Vector3f TunnelLight::GetPosition()
{
	return pModel->getPosition();
}
void TunnelLight::SetVisiblity(const float value)
{
	COLOR3F color = mColor * value;// COLOR3F(value,value,value);
	pLight->SetDiffuseColor(color);
	pFlare->setColor(color * 0.02);
}

void TunnelLight::SetPosition(const Vector3f& position)
{
	Vector3f flareOffset = Vector3f(0.35,-1.5,0.5);
	pFlare->setPosition(position + flareOffset);
	if(SHOW_PROPS)
		pModel->setPosition(position);
	pLight->SetPosition(position);
	pLight->SetAttenuation(4);
}
HRESULT TunnelLight::Create()
{
	Release();

	if(SHOW_PROPS)
		if(FAILED(CEngine::GetInstance()->CreateObject(string("LightA.mdl"), &pModel, MODEL_MESH)))
		{
			Release();
			EE_EXCEPTION("Failed to create light model.");
		}
	
	if(FAILED(CEngine::GetInstance()->GetRenderer()->CreateLight(&pLight)))
	{
		Release();
		EE_EXCEPTION("Failed to create light.");
	}

	if(FAILED(CEngine::GetInstance()->GetRenderer()->CreatePointsprite(
		string("effects/tunnellight_flare.dds"), &pFlare)))
	{
		Release();
		throw EE_EXCEPTION("Failed to load traffic light lense flare");
	}

	mColor = COLOR3F(0.7 + CUtil::random(0.08f),0.9+ CUtil::random(0.2f),1+ CUtil::random(0.2f)) * 18;
	pLight->SetAttenuation(6.5f);
	pLight->SetDiffuseColor(mColor); 
	pLight->SetAmbientColor(COLOR3F()); 

	if(SHOW_PROPS)
	{
		pModel->getModel()->setRenderFlags(RENDER_DEFAULT);
		pModel->setTransform(MATRIX4X4F::translate(Vector3f(26.17f,0,0)));
	}

	pFlare->setRenderFlags(RENDER_TRANSPARENT);
	pFlare->setRadius(200);
	pFlare->setColor(mColor);//COLOR3F(.1,.15,0.05));
	

	return S_OK;
}
void TunnelLight::Update(float dt)
{
	pLight->SetState(D3DLight::LIGHT_ON );
}
void TunnelLight::Draw()
{
	if(SHOW_PROPS)
		pModel->Draw();

	pFlare->Draw();
//	pFlare->setColor(COLOR3F(.1,.115,0.120));

}
HRESULT TunnelLight::Release()
{
	if(pModel)
	{
		pModel->Release();
		pModel = NULL;
	}
	pLight = NULL;
	pFlare = NULL;
	return S_OK;
}

TrafficLight::TrafficLight()
{
	mDuration = CUtil::random(100.0f);
	pModel = NULL;
	pLight = NULL;
	pFlare = NULL;
	pLenseFlareA = NULL;
}

TrafficLight::~TrafficLight()
{
//	Release();
}

void TrafficLight::SetPosition(const Vector3f& positon)
{
//	Vector3f position = Vector3f(26.17f,5,0);

	pLenseFlareA->setRenderFlags(RENDER_TRANSPARENT);
	pLenseFlareA->setPosition(Vector3f(26.17f,0,0));

	if(SHOW_PROPS)
	{
		pModel->getModel()->setRenderFlags(RENDER_DEFAULT);
		pModel->setPosition(positon);
	}

	Vector3f flareOffset = Vector3f(0.35,10,0.5);
	pFlare->setPosition(positon + flareOffset);
	pLight->SetPosition(positon);
}
Vector3f TrafficLight::GetPosition()
{
	return (SHOW_PROPS) ? pModel->getPosition() : Vector3f() ;
}
HRESULT TrafficLight::Release()
{
	if(!ISNULL(pModel))
	{
		CEngine::GetInstance()->UnregisterObject(pModel);
		pModel = NULL;
	}
	if(!ISNULL(pLight))
	{
		pLight->Release();
		pLight = NULL;
	}
	return S_OK;
}

HRESULT TrafficLight::Create()
{
	Release();

	if(FAILED(CEngine::GetInstance()->GetRenderer()->CreatePointsprite(
		string("effects/lenseflare_a.dds"), &pLenseFlareA)))
	{
		Release();
		throw EE_EXCEPTION("Failed to load traffic light lense flare");
	}

	if(SHOW_PROPS)
	{
		if(FAILED(CEngine::GetInstance()->CreateObject(string("TrafficLight.mdl"), &pModel, MODEL_MESH)))
		{
			Release();
			throw EE_EXCEPTION("Failed to load traffic light model");
		}
	}	

	if(FAILED(CEngine::GetInstance()->GetRenderer()->CreatePointsprite(
		string("effects/trafficlight_glow.dds"), &pFlare)))
	{
		Release();
		throw EE_EXCEPTION("Failed to load traffic light glow");
	}

	if(FAILED(CEngine::GetInstance()->GetRenderer()->CreateLight(&pLight)))	
	{
		Release();
		throw EE_EXCEPTION("Failed to load traffic light");
	}

	Vector3f position = Vector3f(26.17f,5,0);

	pLenseFlareA->setRenderFlags(RENDER_TRANSPARENT);
	pLenseFlareA->setPosition(Vector3f(26.17f,0,0));

	if(SHOW_PROPS)
	{
		pModel->getModel()->setRenderFlags(RENDER_DEFAULT);
		pModel->setPosition(position);
	}

	Vector3f flareOffset = Vector3f(0.35,10,0.5);
	pFlare->setPosition(position + flareOffset);
	pFlare->setRenderFlags(RENDER_TRANSPARENT);
	pFlare->setRadius(200);
	pFlare->setColor(COLOR3F(1,.25,0));
	

	pLight->SetAttenuation(6.5f);
	pLight->SetDiffuseColor(COLOR3F(0.7 + CUtil::random(0.08f),0.9+ CUtil::random(0.2f),1+ CUtil::random(0.2f)) * 8); 
	pLight->SetAmbientColor(COLOR3F()); 
	pLight->SetLightCoefficents(0,0,1);
	pLight->SetPosition(position);

	return S_OK;
}

Vector3f GetLenseFlareVector(const Vector3f &lightPosition)
{
	Vector3f line0Pos = CEngine::GetInstance()->GetCamera()->getPosition();
	Vector3f line0Dir = CEngine::GetInstance()->GetCamera()->getDirection();
	Vector3f::normalize(&line0Dir);

	Vector3f line1Pos = lightPosition;
	Vector3f line1Dir = lightPosition - line0Pos;
	Vector3f::normalize(&line1Dir);

	Vector3f diff = line0Pos - line1Pos;
	float a01 = -Vector3f::dot(&line0Dir, &line1Dir);
	float b0 = Vector3f::dot(&line0Dir, &diff);
	float c = Vector3f::dot(&diff,&diff);
	float det = 1 - a01 * a01;
	float sqrtDist = 0.0; 
	float fB1, fS0, fS1, fSqrtDist;

	if(fabs(det) >= EPSILON)
	{
		float b1 = -Vector3f::dot(&line1Dir, &diff);
		float invDet = 1.0f / det;
		float l0Closest = (a01 * b1 - b0) * invDet;
		float l1Closest = (a01 * b0 - b1) * invDet;
		sqrtDist = l0Closest * (l0Closest + a01 * l1Closest + 2 * b0) +
			l1Closest * (a01 * l0Closest + l1Closest + 2 * b1) + c;

	}
	else
	{
		float l0Closest = -b0;
		float l1Closest = 0;
		sqrtDist = b0 * l0Closest + c;
	}
	
	Vector3f vRight = Vector3f::cross(&line0Dir, &line1Dir);
	Vector3f vfvDir = Vector3f::cross(&line0Dir, &vRight);
	Vector3f::normalize(&vfvDir);

	return (vfvDir * sqrtf(fabs(sqrtDist)));
}

void TrafficLight::Update(float dt)
{
	Vector3f cameraPosition = CEngine::GetInstance()->GetCamera()->getPosition();
	Vector3f modelPosition = (SHOW_PROPS) ? pModel->getPosition() : Vector3f();


	Vector3f flareOffset = Vector3f(0.35,10,0);
	mDuration += dt;

#define THRESHOLD 300
	if(cameraPosition.x - modelPosition.x < -THRESHOLD)
	{

		modelPosition.x -= (THRESHOLD * 2);
		pModel->setPosition(modelPosition);
		pLight->SetPosition(modelPosition);
		pFlare->setPosition(modelPosition + flareOffset);
	}
	else if(cameraPosition.x - modelPosition.x > THRESHOLD)
	{
		modelPosition.x += (THRESHOLD * 2);
		pModel->setPosition(modelPosition);
		pLight->SetPosition(modelPosition);
		pFlare->setPosition(modelPosition+ flareOffset);
	}
	float dist = Vector3f::distance(&cameraPosition, &modelPosition) * 0.00005f;
	pFlare->setRadius(1.0f / dist);

	Vector3f lenseFlareVector = GetLenseFlareVector(modelPosition);
	pLenseFlareA->setPosition(modelPosition + (lenseFlareVector * 0.55));

	if(SHOW_PROPS)
		pModel->Update(dt);
}

void TrafficLight::Draw()
{
	int onCheck = (int)(22*mDuration);
	if((onCheck % 2) == 0)
	{
		pFlare->Draw();
		pLight->SetState(D3DLight::LIGHT_ON);
//pLight->s
	}
	else
		pLight->SetState(D3DLight::LIGHT_OFF);

	if(SHOW_PROPS)
		pModel->Draw();

	pLight->SetAttenuation(0.5f);
	pLight->SetDiffuseColor(COLOR3F(5,0,0));
	pLight->SetAmbientColor(COLOR3F(0.17,0.15,0.16));
	pLight->SetLightCoefficents(.35,0.1,3);
	
	pLight->SetLightCoefficents(0,1,5);

	pLenseFlareA->Draw();
	Vector3f cameraPosition = CEngine::GetInstance()->GetCamera()->getPosition();
	Vector3f cameraDir = CEngine::GetInstance()->GetCamera()->getDirection();

}

Train::Train() : HEADLIGHT_COUNT(2)
{
	m_Velocity = 400.0f;
	m_Phase = 0.0f;
	m_CarraigeCount = 0;
	pCarraiges = NULL;
	pCarraigeLights = NULL;

	for(unsigned int i = 0; i < HEADLIGHT_COUNT; i++)
	{
		pHeadLights[i] = NULL;
		pHeadLightLensEffects[i] = NULL;
	}
}

void Train::SetMidpoint(const Vector3f& midpoint)
{
	m_MidPoint = midpoint;
}
void Train::SetVelocity(const float velocity)
{
	m_Velocity = (velocity == 0.0f) ? 1.0f : velocity;

}

HRESULT Train::Create(unsigned int carraigeCount)
{
	if(FAILED(Release()))
		return E_FAIL;

	m_CarraigeCount = (carraigeCount == 0) ? 1 : carraigeCount;
	pCarraiges = EE_NEW CObject* [m_CarraigeCount];

	for(int i = 0; i < m_CarraigeCount; i++)
	{
		if(SUCCEEDED(CEngine::GetInstance()->CreateObject(string("Subway.mdl"), &pCarraiges[i], MODEL_MESH)))
		{
			pCarraiges[i]->getModel()->setRenderFlags(RENDER_DEFAULT);
			pCarraiges[i]->setPosition(Vector3f(i * 50.5,2.5,-33.5));
			pCarraiges[i]->setVelocity(Vector3f(1600,0,0));
		}
		
	}

	pCarraigeLights = EE_NEW D3DLight* [m_CarraigeCount / 2];
	
	for(int i = 0; i < m_CarraigeCount / 2; i++)
	{
		if(SUCCEEDED(CEngine::GetInstance()->GetRenderer()->CreateLight(&pCarraigeLights[i])))
		{
			pCarraigeLights[i]->SetAttenuation(6.5f); 
			pCarraigeLights[i]->SetDiffuseColor(COLOR3F(0.7 + CUtil::random(0.08f),0.9+ CUtil::random(0.2f),1+ CUtil::random(0.2f)) * 8); 
			pCarraigeLights[i]->SetAmbientColor(COLOR3F()); 
		}
	}

	for(int i = 0; i < HEADLIGHT_COUNT; i++)
	{
		if(FAILED(CEngine::GetInstance()->GetRenderer()->CreatePointsprite(
			string("effects/train_flare.dds"), &pHeadLightLensEffects[i])))
		{
			Release();
			throw EE_EXCEPTION("Failed to load traffic light lense flare");
		}

		pHeadLightLensEffects[i]->setRenderFlags(RENDER_TRANSPARENT);
		pHeadLightLensEffects[i]->setRadius(200);
		//pHeadLightLensEffects[i]->setColor(COLOR3F(1,.25,0));
	}

	return S_OK;
}

void Train::Update(float dt)
{	
	CCamera* pCamera = CEngine::GetInstance()->GetCamera();
	for(int i = 0; i < m_CarraigeCount; i++)
	{
		Vector3f carraigePosition = pCarraiges[i]->getPosition();
		if(carraigePosition.x > pCamera->getPosition().x + pCamera->getFarPlane())
			pCarraiges[i]->setPosition(Vector3f(pCamera->getPosition().x - pCamera->getFarPlane(),carraigePosition.y,carraigePosition.z));
						
		pCarraiges[i]->Update(dt);
	}

	for(int i = 0; i < m_CarraigeCount / 2; i++)
	{
		Vector3f carraigePosition = pCarraiges[i * 2]->getPosition();
		pCarraigeLights[i]->SetPosition(carraigePosition - Vector3f(22,7,15));
		pCarraigeLights[i]->SetDiffuseColor(COLOR3F((238.0f / 256.0f),(262.0f / 256.0f),(240.0f / 256.0f)) * 35);
		pCarraigeLights[i]->SetAttenuation(1);
		pCarraigeLights[i]->SetLightCoefficents(0,.2,2);
	}


}

void Train::Draw()
{
	for(int i = 0; i < m_CarraigeCount; i++)
	{
		pCarraiges[i]->Draw();
	}

	
	CCamera* pCamera = CEngine::GetInstance()->GetCamera();
	if(m_CarraigeCount > 0)
	{
		Vector3f frontPosition = pCarraiges[m_CarraigeCount-1]->getPosition();
		
		float dist = Vector3f::distance(&pCamera->getPosition(), &frontPosition);

#define START_GLOW 300
#define END_GLOW 175
		if(dist < START_GLOW)
		{
			if(dist > END_GLOW)
			{
				float alpha = (START_GLOW-dist) / (START_GLOW - END_GLOW);
				pHeadLightLensEffects[0]->setColor(COLOR3F(alpha,alpha,alpha));
				pHeadLightLensEffects[1]->setColor(COLOR3F(alpha,alpha,alpha));
			}
			else
			{
				
				pHeadLightLensEffects[0]->setColor(COLOR3F(1,1,1));
				pHeadLightLensEffects[1]->setColor(COLOR3F(1,1,1));
			}
			pHeadLightLensEffects[0]->Draw();
			pHeadLightLensEffects[1]->Draw();

			Vector3f flareOffset = Vector3f(32.35,0.45,2.5);
			pHeadLightLensEffects[0]->setPosition(frontPosition+ flareOffset);
			flareOffset = Vector3f(32.35,0.45,-2.5);
			pHeadLightLensEffects[1]->setPosition(frontPosition+ flareOffset);
			
			dist *= 0.00005;
			pHeadLightLensEffects[0]->setRadius(1.0f/dist);
			pHeadLightLensEffects[1]->setRadius(1.0f/dist);
		}
	}
}

HRESULT Train::Release()
{
	HRESULT result = S_OK;
	for(int i = 0; i < m_CarraigeCount; i++)
	{
		CEngine::GetInstance()->UnregisterObject(pCarraiges[i]);
		pCarraiges[i] = NULL;
	}
	for(int i = 0; i < m_CarraigeCount / 2; i++)
	{
		if(FAILED(pCarraigeLights[i]->Release()))
			result = E_FAIL;
	}

	EE_SAFEDELETEARRAY(pCarraigeLights);
	EE_SAFEDELETEARRAY(pCarraiges);

	m_CarraigeCount = 0;

	
	for(unsigned int i = 0; i < HEADLIGHT_COUNT; i++)
	{
		if(!ISNULL(pHeadLights[i]))
			if(FAILED(pHeadLights[i]->Release()))
				result = E_FAIL;
		if(!ISNULL(pHeadLightLensEffects[i]))
			if(FAILED(pHeadLightLensEffects[i]->Release()))
			result = E_FAIL;
		pHeadLights[i] = NULL;
		pHeadLightLensEffects[i] = NULL;
	}

	return S_OK;
}